/*
 * Controller test class
 * Author: Jonathan Forbes
 * TCSS 360 (Group project) Spring 2013 
 * University of Washington
 */
package View;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import Model.Controller;
import Model.User;

/**
 * Primary class for the User Settings Tab
 * 
 * @author Jonathan Forbes
 * @version 1.0
 */
public class UserSettings extends JPanel {

	private static final long serialVersionUID = -4552882380617757898L;
	private Controller controller;
	private User currentUser;
	private JLabel lblNameError;
	private JLabel lblLoginError;
	private JLabel lblEmailError;
	private JLabel lblPasswordError; 
	private JLabel lblPasswordRegError;
	private JLabel lblPassword2Error;
	private JTextField txtName;
	private JTextField txtLoginReg;
	private JTextField txtEmail;
	private JPasswordField txtPasswordOld;
	private JPasswordField txtPasswordReg;
	private JPasswordField txtPassword2;
	private JButton applyChanges;	
	
	/**
	 * Constructor for the UserSettings class.
	 * @param Controller the controller for the program
	 */
	public UserSettings(final Controller control) {
		controller = control;
		currentUser = controller.getCurrentUser();
		setup();
	}
	
	/**
	 * Method that will setup the look and layout of the
	 * User Settings tab.
	 * 
	 */
	private void setup() {
		//Create Labels for the TextFields and add to array
		JLabel lblName = new JLabel("Full Name: ");
		JLabel lblLogin = new JLabel("Username: ");
		JLabel lblEmail = new JLabel("Email: ");
		JLabel lblOldPass = new JLabel("Old Password: ");
		JLabel lblNewPass = new JLabel("New Password: ");
		JLabel lblConfPass = new JLabel("Confirm Password: ");				  
		JLabel [] labels = {lblName, lblLogin, lblEmail, lblOldPass, lblNewPass, lblConfPass};

		//Create labels to display errors while changing settings. Add to array, then format the color
		lblNameError = new JLabel("Please type your full name");
		lblLoginError = new JLabel("Please type your desired Username");
		lblEmailError = new JLabel("Please type your Email adress");
		lblPasswordError = new JLabel("Please enter your password to make changes"); 
		lblPasswordRegError = new JLabel();
		lblPassword2Error = new JLabel("Passwords do not match. Please try again"); 				  
		JLabel [] errorLabels = {lblNameError, lblLoginError, lblEmailError, lblPasswordError, lblPasswordRegError, lblPassword2Error};

		lblNameError.setForeground(Color.red);
		lblLoginError.setForeground(Color.red);
		lblEmailError.setForeground(Color.red);
		lblPasswordError.setForeground(Color.red);
		lblPasswordRegError.setForeground(Color.red);
		lblPassword2Error.setForeground(Color.red);

		//Create TextFields for information entry on user settings tab, add to array
		txtName = new JTextField(currentUser.getfullname(), 12);
		txtLoginReg = new JTextField(currentUser.getLogin(), 12);
		txtEmail = new JTextField(currentUser.getEmail(), 12);
		txtPasswordOld = new JPasswordField(12);
		txtPasswordReg = new JPasswordField(12);
		txtPassword2 = new JPasswordField(12);
		JTextField [] textFields = {txtName, txtLoginReg, txtEmail, txtPasswordOld, txtPasswordReg, txtPassword2};

		//Set default size of textFields
		Dimension textSize = new Dimension(100, 25);
		txtName.setPreferredSize(textSize);
		txtLoginReg.setPreferredSize(textSize);
		txtEmail.setPreferredSize(textSize);
		txtPasswordOld.setPreferredSize(textSize);
		txtPasswordReg.setPreferredSize(textSize);
		txtPassword2.setPreferredSize(textSize);

		//Add labels for Textfields
		lblName.setLabelFor(txtName);
		lblLogin.setLabelFor(txtLoginReg);
		lblEmail.setLabelFor(txtEmail);
		lblOldPass.setLabelFor(txtPasswordOld);
		lblNewPass.setLabelFor(txtPasswordReg);
		lblConfPass.setLabelFor(txtPassword2);

		//Add button to apply changes to user settings
		applyChanges = new JButton("Apply Changes");

		//Create Layout and apply to tab
		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		this.setLayout(gridbag);

		//Set GridBag constraints
		c.gridwidth = GridBagConstraints.REMAINDER; //last
		c.anchor = GridBagConstraints.WEST;
		c.weightx = 1.0;

		addLabelTextRows(labels, textFields, errorLabels, gridbag, this);
		lblNameError.setVisible(false);
		lblLoginError.setVisible(false);
		lblEmailError.setVisible(false);
		lblPasswordError.setVisible(false);
		lblPasswordRegError.setVisible(false);
		lblPassword2Error.setVisible(false);

		applyChanges.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent the_event) {	
				lblNameError.setVisible(false);
				lblLoginError.setVisible(false);
				lblEmailError.setVisible(false);
				lblPasswordError.setVisible(false);
				lblPasswordRegError.setVisible(false);
				lblPassword2Error.setVisible(false);
				if (the_event.getSource() == applyChanges) { //Check button source
					if(!txtName.getText().isEmpty()) { //Name not Empty
						if(!txtLoginReg.getText().isEmpty()) { //Login not Empty
							if(controller.uniqueUsername(txtLoginReg.getText()) || txtLoginReg.getText().equals(currentUser.getLogin())) { //If user login is Unique (or same as before)
								if(!txtEmail.getText().isEmpty() && controller.emailContainsAt(txtEmail.getText())) { //Email not empty
									if(controller.checkPasswordSame(new String(txtPasswordOld.getPassword()), currentUser.getPassword())) { // Old Password is correctly entered
										if(!(txtPasswordReg.getPassword().length == 0 && txtPassword2.getPassword().length == 0)) { // New Password and Confirm Password are both not blank
											if(controller.checkPasswordSame(new String(txtPasswordReg.getPassword()), new String(txtPassword2.getPassword()))) { // New Password not the same as Confirm Password
												if(controller.checkPasswordSizeCorrect(new String(txtPasswordReg.getPassword()))) {
													
													/* If we get here, there are no User Input errors
													 * on the user settings tab. Now let's try to change
													 * the settings the user has asked to change.
													 */
													if(controller.changeUserSettings(txtLoginReg.getText(), txtName.getText(), txtEmail.getText(), new String(txtPasswordReg.getPassword()))) {
														JOptionPane.showMessageDialog(null, "Changes have been applied.");
														System.out.println(txtLoginReg.getText());
														System.out.println(controller.getCurrentUsername());
														txtPasswordOld.setText("");
														txtPasswordReg.setText("");
														txtPassword2.setText("");
													} else {
														JOptionPane.showMessageDialog(null, "Changes unsuccessful!.");
													}

												}
												else {//Password not correct length >= 8
													lblPassword2Error.setText("Error - Password must be atleast 8 characters.");
													lblPassword2Error.setVisible(true);
												}
											}
											else {//Password Box 2 Empty
												lblPassword2Error.setText("Error - Password Confirmation not the same as New Password.");
												lblPassword2Error.setVisible(true);
											}
										}
										else {//Both New and Confirm Password are empty
											
											/* If we get here, the user wants to change either the
											 * name, login, or email, but does not want to change
											 * their password.
											 */
											if(controller.changeUserSettings(txtLoginReg.getText(), txtName.getText(), txtEmail.getText(), new String(txtPasswordOld.getPassword()))) {
												JOptionPane.showMessageDialog(null, "Changes have been applied.");
												System.out.println(txtLoginReg.getText());
												System.out.println(controller.getCurrentUsername());
												txtPasswordOld.setText("");
											} else {
												JOptionPane.showMessageDialog(null, "Changes unsuccessful!.");
											}
										}
									}
									else {//Password Box 1 empty
										lblPasswordError.setText("Error - Password needed to make changes.");
										lblPasswordError.setVisible(true);
									}
								}
								else {//Email was empty
									lblEmailError.setText("Error - Email Empty or does not contain \"@\" or \".\"");
									lblEmailError.setVisible(true);
								}
							}
							else {//User not UNIQUE
								lblPassword2Error.setText("Error - Username already Exists.");
								lblPassword2Error.setVisible(true);
							}
						}
						else {//Login was empty
							lblLoginError.setText("Error - Username Empty.");
							lblLoginError.setVisible(true);
						}
					}
					else { //Name was empty
						lblNameError.setText("Error - Name Empty.");
						lblNameError.setVisible(true);
					}
				}
			}
		});
	}

	/**
	 * Helper method that will the LabelTextRows to the container
	 * using the gridBag layout.
	 * @param JLabel[] array of labels to be added
	 * @param JTextField[] textFields to be added
	 * @param JLabel[] errorLabels to be added
	 * @param GridBagLayout gridbag the layout created above
	 * @param Container container to put these components on
	 */
	private void addLabelTextRows(JLabel[] labels, 
			JTextField[] textFields,
			JLabel[] errorLabels,
			GridBagLayout gridbag,
			Container container) {

		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.EAST;
		int numLabels = labels.length;

		for (int i = 0; i < numLabels; i++) {
			c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last
			c.fill = GridBagConstraints.NONE;      //reset to default
			c.weightx = 0.0;                       //reset to default
			container.add(labels[i], c);

			c.gridwidth = GridBagConstraints.REMAINDER;     //end row
			c.fill = GridBagConstraints.HORIZONTAL;
			c.weightx = 1.0;
			container.add(textFields[i], c);
			container.add(errorLabels[i], c);
		}
		JPanel spaceBuff1 = new JPanel();
		c.gridwidth = GridBagConstraints.REMAINDER;     //end row
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 1.0;
		container.add(spaceBuff1, c);

		c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last
		c.fill = GridBagConstraints.NONE;      //reset to default
		c.weightx = 0.0;                       //reset to default
		JPanel spaceBuff2 = new JPanel();


		container.add(spaceBuff2, c);
		container.add(applyChanges, c);
	}

	/**
	 * Used to print out title for tabbed panes.
	 */
	public String getName() {
		return "User Settings";
	} //getName
}
